function Promise(executor) {
    let self = this;
    self.value = undefined;
    self.reason = undefined;
    // 管理Promise状态
    self.status = 'pending';
    self.onResolvedCallbacks = [];
    self.onRejectedCallbacks = [];
    let saber

    let resolve = (value) => {
        // 只有状态是pending时，才可以转变状态
        if (self.status === 'pending') {
            self.status = 'fulfilled';
            self.value = value;
            // 执行成功方法，数组为空时不会执行
            self.onResolvedCallbacks.forEach(fn => {
                fn();
            });
        }
    }

    let reject = (reason) => {
        // 只有状态是pending时，才可以转变状态
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
            // 执行失败方法，数组为空时不会执行
            self.onRejectedCallbacks.forEach(fn => {
                fn();
            })
        }
    }


    try {
        // 如果传进来的函数报错 直接让Promise失败
        executor(resolve, reject);
    } catch (e) {
        reject(e);
    }
}

// 核心 处理 promise2 与 x 之间的关系
function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        // 无限循环了
        return reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'))
    }
    let called;
    // x 可能是别人实现的promise
    // 如果 x 是个promise，x 先必须是个函数或对象。
    if ((x !== null && typeof x === 'object') || typeof x === 'function') {
        try {
            let then = x.then;
            // 如果 x 有 then 这个属性，并且是个方法，那么 x 有可能是个promise
            if (typeof then === 'function') {
                then.call(x, (y) => {
                    // 避免resolve、reject都被调用了
                    if (!called) { called = true; } else { return; }
                    // 递归检查promise，一直到 x 是一个普通值为止
                    resolvePromise(x, y, resolve, reject);
                }, (r) => {
                    if (!called) { called = true; } else { return; }
                    reject(r);
                })
            } else {
                if (!called) { called = true; } else { return; }
                // x 是个普通值，直接成功返回
                resolve(x);
            }
        } catch (e) {
            // then 方法出错，直接走失败逻辑
            if (!called) { called = true; } else { return; }
            reject(e)
        }
    } else {
        if (!called) { called = true; } else { return; }
        // x 是个普通值，直接成功返回
        resolve(x)
    }
}

// 公用方法，挂在原型上
// 为了实现then方法的链式调用，所以then方法应该返回一个Promise实例
// 坑，这处不能用箭头函数，this会被指向构造函数，而不是Promise实例
Promise.prototype.then = function (onFulfilled, onRejected) {
    // onFulfilled、onRejected 可能没传，那就默认给他个函数返回value、reason，让then的链式调用不会断掉
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (data) => {
        return data
    }
    onRejected = typeof onRejected === 'function' ? onRejected : (err) => {
        throw err
    }
    let self = this;
    let promise2;
    /**
     * 这个promise2 就是我们每次调用then后返回的新的promise
     * 实现链式调用主要的靠的就是这个promise
     * 直接把上一个外层promise的两个私有方法传进去
     * 因为处理promise2与x之间的关系，所以只能用异步方法先让promise2有值
     * es6中的promise似乎用的事异步队列中的微任务，这里没法实现所以只能用宏任务setTimeout代替
     * 微任务执行在宏任务之前
     * 因为onFulfilled、onRejected可能会有返回值,且返回值可能也是个promise,所以要处理promise2与x之间的关系
     */
    promise2 = new Promise((resolve, reject) => {
        // onFulfilled、onRejected可能本身就有出错，直接走reject;
        if (self.status === 'fulfilled') {
            setTimeout(() => {
                try {
                    let x = onFulfilled(self.value);
                    // 判断promise2 和 x，也是then函数返回的结果和promise2的关系 如果x 是普通值 那就让promise2成功 如果 是一个失败的promise那就让promise2 失败
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0)
        }
        if (self.status === 'rejected') {
            setTimeout(() => {
                try {
                    let x = onRejected(self.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0)
        }
        // executor可能有异步方法，所以也要判断pending
        if (self.status === 'pending') {
            // 同样要处理onFulfilled、onRejected出错的情况，所以直接那个函数把它包起来
            self.onResolvedCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(self.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            });
            self.onRejectedCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        let x = onRejected(self.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                }, 0)
            })
        }
    })

    return promise2
}

// 实际上就是调用只传了onRejected的then方法
Promise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected)
}

// 实际上就是调用了onFulfilled, onRejected中都调用fn函数的then方法
Promise.prototype.finally = function (fn) {
    return this.then((data) => {
        fn();
        return data;
    }, (err) => {
        fn();
        throw err
    })
}

// 类调用的方法都叫静态方法
// 实际上就是返回直接resolve的promise实例
Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
        resolve(value);
    })
}

// 实际上就是返回直接reject的promise实例
Promise.reject = function (err) {
    return new Promise((resolve, reject) => {
        reject(err);
    })
}

/**
 * 做个计数器，promise成功返回次数足够才调resolve，任何一个失败都走reject
 */
Promise.all = function (promises) {
    return new Promise((resolve, reject) => {
        let count = 0;
        let arr = [];
        function processData (index, data) {
            arr[index] = data;
            if (++count === promises.length) {
                resolve(arr);
            }
        }
        for (let i in promises) {
            let promise = promises[i];
            if (typeof promise.then === 'function') {
                promise.then((data) => {
                    processData(i, data)
                }, reject)
            } else {
                processData(i, promise);
            }
        }
    })
}

// 只要有一个promise返回了，任何一个失败都走reject
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i in promises) {
            let promise = promises[i];
            if (typeof promise.then === 'function') {
                promise.then(resolve, reject)
            } else {
                resolve(promise)
            }
        }
    })
}

Promise.deferred = Promise.defer = function () {
    let dfd = {};
    dfd.promise = new Promise((resolve, reject) => {
        dfd.resolve = resolve;
        dfd.reject = reject;
    })
    return dfd
}

module.exports = Promise;